﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;

/// <summary>
/// Summary description for Validation
/// </summary>
public class Validation
{
    Service service = new Service();
    private List<string> errormessages = new List<String>();
    private Hashing hash = new Hashing();

    private const int UsernameMinLength = 8;
    private const int UsernameMaxLength = 50;
    private const int PasswordMinLength = 8;
    private const int PasswordMaxLength = 50;

    //TODO :: ERRORMESSAGES FÖR REGISTER VALIDATION OCH LOGIN VALIDATION
    public bool LoginValidation(string username, string password, string repeatPassword = null, string email = "")
    {
        bool validLoginInfo = true;

        if (!ValidateUsernameLength(username))
        {
            validLoginInfo = false;
        }
        if (!ValidateUsernameCharacters(username))
        {
            validLoginInfo = false;
        }
        
        if (!ValidatePasswordLength(password))
        {
            validLoginInfo = false;
        }
        if (!ValidatePasswordCharacters(password))
        {
            validLoginInfo = false;
        }
        if (repeatPassword != null)
        {
            if (UsernameExists(username))
            {
                validLoginInfo = false;
            }
            if (!ValidatePasswordLength(repeatPassword))
            {
                validLoginInfo = false;
            }
            if (!ValidatePasswordCharacters(repeatPassword))
            {
                validLoginInfo = false;
            }
            if (!ComparePasswords(password, repeatPassword))
            {
                validLoginInfo = false;
            }
            if (!EmailLengthValidation(email))
            {
                validLoginInfo = false;
            }
            if (!EmailValidation(email))
            {
                validLoginInfo = false;
            }

        }
        return validLoginInfo;
    }



    public bool ValidateProfileInfo(string email, string signature)
    {
        bool isValid = true;
        if (!EmailValidation(email))
        {
            isValid = false;
        }
        if (!EmailLengthValidation(email))
        {
            isValid = false;
        }
        if (signature != "")
        {
            ValidateSignatureLength(signature);
        }
        return isValid;
    }

    public bool ValidateNewTopic(string header, string content)
    {
        bool isValid = true;
        if (!ValidateTopicHeaderLength(header))
        {
            isValid = false;
        }
        if (!ValidateTopicContentLength(content))
        {
            isValid = false;
        }
        return isValid;
    }

    private bool ValidateSignatureLength(string signature)
    {
        if (signature.Count() > 0 && signature.Count() < 150)
        {
            return true;
        }
        AddErrorMessage("The signature cant be more then 150 Characters long.");
        return false;
    }




    #region USERNAME AND PASSWORD VALIDATION

    public bool UsernameExists(string username)
    {
        UserCredentials userC = service.GetUserCredentialsOnUsername(username);
        if (userC != null)
        {
            if (username == userC.Username)
            {
                AddErrorMessage("The Username Already Exists, Please Pick Another Username.");
                return true;
            }
        }
        return false;
    }

    public bool IsCorrectUsernameAndPassword(string username, string password)
    {
        UserCredentials userC = service.GetUserCredentialsOnUsername(username);
        if (userC.Username != username || userC.Password != hash.HashPassword(password, userC.Salt))
        {
            if (userC.UserID == 0)
            {
                AddErrorMessage("Wrong Username And/Or Password.");
            }
            else
            {
                AddErrorMessage("Wrong Username And/Or Password.");
            }
            return false;
        }

        return true;
    }

    private bool ValidateUsernameLength(string username)
    {
        int usernameLength = username.Length;
        if (usernameLength < UsernameMinLength || usernameLength > UsernameMaxLength)
        {
            AddErrorMessage("The Username Must Be Between 8-50 Characters!");
            return false;
        }
        return true;
    }

    public bool ValidateUsernameCharacters(string username)
    {
        if (!Regex.IsMatch(username, "^[0-9a-zA-Z]*$"))
        {
            AddErrorMessage("Invalid username - Only characters from 'a-z, A-Z and 0-9 are allowed.' ");
        }
        return true;
    }



    private bool ValidatePasswordLength(string password)
    {
        int passwordLength = password.Length;
        if (passwordLength < PasswordMinLength || passwordLength > PasswordMaxLength)
        {
            AddErrorMessage("The Password Must Be Between 8-50 Characters!");
            return false;
        }
        return true;
    }


    private bool ValidatePasswordCharacters(string password)
    {
        if (!Regex.IsMatch(password, "^[0-9a-zA-Z]*$"))
        {
            AddErrorMessage("Invalid password - - Only characters from 'a-z, A-Z and 0-9 are allowed.'");
        }
        return true;
    }

    public bool ComparePasswords(string firstPass, string secondPass)
    {
        if (firstPass == secondPass)
        {
            return true;
        }
        return false;
    }

    #endregion

    #region EMAIL VALIDATION

    private bool EmailValidation(string email)
    {
        if (Regex.IsMatch(email, @"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$"))
        {
            return true;
        }
        AddErrorMessage("The Email Format Is Incorrect: an example is: person@mymail.com ");
        return false;
    }

    private bool EmailLengthValidation(string email)
    {
        if (email.Count() > 0 && email.Count() < 50)
        {
            return true;
        }
        AddErrorMessage("Email cannot be more then 50 characters.");
        return false;
    }


    #endregion

    #region TOPIC HEADER TOPIC CONTENT, AND COMMENT VALIDATION


    private bool ValidateTopicHeaderLength(string sanitizedHeader)
    {
        if (sanitizedHeader.Count() > 0 && sanitizedHeader.Count() < 150)
        {
            return true;
        }
        AddErrorMessage("The Header Must Be Between 1-150 Characters.");
        return false;
    }

    private bool ValidateTopicContentLength(string sanitizedContent)
    {
        if (sanitizedContent.Count() > 0 && sanitizedContent.Count() < 2000)
        {
            return true;
        }
        AddErrorMessage("The Topic Must Be Between 1 and 2000 Characters.");
        return false;
    }

    public bool ValidateCommentContentLength(string sanitizedContent)
    {
        if (sanitizedContent.Length > 0 && sanitizedContent.Length < 2000)
        {
            return true;
        }
        AddErrorMessage("The Comment Must Be Between 1-2000 Characters. ");
        return false;
    }

    #endregion

    #region OTHER METHODS - (sanitize)

    public string SanitizeText(string text)
    {
        return HttpUtility.HtmlEncode(text);
    }

    #endregion

    #region GET & SET ERRORMESSAGES.

    public List<string> GetErrorMessages()
    {
        return errormessages;
    }

    private void AddErrorMessage(string errormessage)
    {
        errormessages.Add(errormessage);
    }

    #endregion

    public bool IfUserWithIDWroteTopicWithID(int userID, int topicID)
    {
        OneTopic topic = service.GetTopicOnID(topicID);

        if (userID == topic.UserID)
        {
            return true;
        }
        AddErrorMessage("Only The Author Can Delete Or Edit This Topic");
        return false;

    }

}